package fsclient

import (
	"bytes"
	"encoding/binary"
	"errors"
	"net"

	"github.com/astaxie/beego"
)

type task_result struct {
	session int
	result  int
}

var headFrame uint32 = 0xaa55eeaa

func protoDecodeInt(serv net.Conn) (uint32, error) {

	var num uint32
	buffer := make([]byte, 4)

	recvlen, err := serv.Read(buffer)
	if err != nil {
		beego.Error("recv failed.", err)
		return 0, err
	}
	if 4 != recvlen {
		beego.Error("recv lenth.", recvlen)
		return 0, errors.New("receive message is less than reqired")
	}

	buf := bytes.NewReader(buffer)
	err = binary.Read(buf, binary.BigEndian, &num)

	return num, err
}

func protoDecodeHead(serv net.Conn) (task *ttsTask, fileNamelen, ttextLen uint32, err error) {

	task = &ttsTask{}
	for i := 0; i < 5; i++ {
		number, er := protoDecodeInt(serv)
		if er != nil {
			beego.Error("wrong message abort.")
			err = er
			return
		}

		beego.Debug(i, "conver to host data: ", number)

		switch i {
		case 0:
			if headFrame != number {
				beego.Error("wrong head frame:", number)
				err = errors.New("wrong head frame")
				return
			}
		case 1:
			task.Session = number
		case 2:
			task.FileType = number
		case 3:
			fileNamelen = number
		case 4:
			ttextLen = number
		}
	}

	return
}

func protoDecodeTask(serv net.Conn) (*ttsTask, error) {

	beego.Debug("waiting for recv task....")
	task, fileNamelen, textLen, err := protoDecodeHead(serv)
	if err != nil {
		beego.Error("proto head failed:", err)
		return nil, err
	}

	beego.Debug("convert task:", task)
	fileName := make([]byte, fileNamelen)
	lenth, err := serv.Read(fileName)

	if lenth != int(fileNamelen) {
		beego.Error("file recv wrong ,recv:", lenth, "decode file name len:", fileNamelen)
		return nil, err
	}

	ttsText := make([]byte, textLen)
	lenth, err = serv.Read(ttsText)

	if lenth != int(textLen) {
		beego.Error("tts text recv wrong ,recv:", lenth, "decode text  len:", textLen)
		return nil, err
	}

	task.FileName = string(fileName[0 : fileNamelen-1])
	task.TtsText = string(ttsText)

	beego.Debug("recv new task:", task)

	return task, nil
}

func encodeInt2Net(buf *bytes.Buffer, result int32) error {

	err := binary.Write(buf, binary.BigEndian, result)
	if err != nil {
		beego.Error("binary.Write failed:", err)
	}

	return err
}

func resultEncode(sessionId, result int32) (*bytes.Buffer, error) {
	buf := new(bytes.Buffer)

	err := encodeInt2Net(buf, (sessionId))
	if err != nil {
		beego.Error("encode to net data failed:", err)
		return nil, err
	}

	err = encodeInt2Net(buf, result)
	if err != nil {
		beego.Error("encode to net data failed:", err)
		return nil, err
	}

	return buf, nil
}
